package org.deltaset.meta.faces;

import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import org.deltaset.faces.component.SelectOption;
import org.deltaset.meta.Catalog;
import org.deltaset.meta.CollectionHandler;
import org.deltaset.meta.EntityResolver;
import org.deltaset.meta.LabelResolver;
import org.deltaset.meta.MetaActionHandler;
import org.deltaset.meta.MetaHandlerFactory;
import org.deltaset.meta.MetaHandlerFactoryBuilder;
import org.deltaset.meta.OptionBuilder;
import org.deltaset.meta.extension.ExecuteListenerProvider;
import org.deltaset.meta.extension.RepositoryProvider;
import org.springframework.stereotype.Component;

/**
 *
 * @author dmakariev
 */
@Component
public class LazyInit {

    private static final String DEFAULT_TEMPLATE_CATALOG_NAME = "META-INF/deltaset/dsTemplateCatalog.properties";
    private static final String DEFAULT_USUPPORTED_TEMPLATE = "/META-INF/resources/deltaset.meta/internal/fields/unsupported.xhtml";
    private final MetaHandlerFactory metaHandlerFactory;
    private final LabelResolver labelResolver;
    private final Catalog catalog;
    private final EntityResolver entityResolver;
    private final CollectionHandler collectionHandler;
    private final MetaActionHandler metaActionHandler;
    private final OptionBuilder<SelectOption> optionBuilder;
    private final GenericEntityConverter genericEntityConverter;
    private final Map<String, String> viewNameTemplateMap;

    @Inject
    LazyInit(final BeanLocator beanLocator) {
        final String catalogName = null;
        final String metaTypeValue = "flow";
        final RepositoryProvider repositoryProvider = beanLocator.getSpringBean(RepositoryProvider.class);
        final ExecuteListenerProvider executeListenerProvider = beanLocator.getSpringBean(ExecuteListenerProvider.class);

        this.metaHandlerFactory = buildMetaHandlerFactory(metaTypeValue, repositoryProvider, executeListenerProvider);
        this.labelResolver = metaHandlerFactory.createLabelResolver();
        this.catalog = metaHandlerFactory.createCatalog(catalogName);
        this.entityResolver = metaHandlerFactory.createEntityResolver();
        this.collectionHandler = metaHandlerFactory.createCollectionHandler();
        this.metaActionHandler = metaHandlerFactory.createMetaActionHandler();
        this.optionBuilder = metaHandlerFactory.createOptionBuilder();
        this.genericEntityConverter = buildGenericEntityConverter(entityResolver);

        this.viewNameTemplateMap = new HashMap<String, String>();
        viewNameTemplateMap.put("detailTemplate", "/META-INF/resources/deltaset.meta/flow/detailTemplate.xhtml");
        viewNameTemplateMap.put("executeTemplate", "/META-INF/resources/deltaset.meta/flow/executeTemplate.xhtml");
        viewNameTemplateMap.put("formTemplate", "/META-INF/resources/deltaset.meta/flow/formTemplate.xhtml");
        viewNameTemplateMap.put("listTemplate", "/META-INF/resources/deltaset.meta/flow/listTemplate.xhtml");
        viewNameTemplateMap.put("defaultView", "listTemplate");
       
    }

    private static MetaHandlerFactory buildMetaHandlerFactory(
            final String metaTypeValue,
            final RepositoryProvider repositoryProvider,
            final ExecuteListenerProvider executeListenerProvider) {
        final MetaHandlerFactoryBuilder builder = MetaHandlerFactoryBuilder.newBuilder();
        builder.catalog(DEFAULT_TEMPLATE_CATALOG_NAME, DEFAULT_USUPPORTED_TEMPLATE, metaTypeValue);
        builder.provider(new CachingMetaHandlerProvider());
        builder.provider(new OptionBuilderProviderImpl());
        builder.provider(repositoryProvider);
        builder.provider(executeListenerProvider);
        final MetaHandlerFactory metaHandlerFactory = builder.build();
        return metaHandlerFactory;
    }

    private static GenericEntityConverter buildGenericEntityConverter(final EntityResolver entityResolver) {
        final GenericEntityConverter genericEntityConverter = new GenericEntityConverter();
        genericEntityConverter.setEntityResolver(entityResolver);
        return genericEntityConverter;
    }

    public Catalog getCatalog() {
        return catalog;
    }

    public Map<String, String> getViewNameTemplateMap() {
        return viewNameTemplateMap;
    }

    public CollectionHandler getCollectionHandler() {
        return collectionHandler;
    }

    public EntityResolver getEntityResolver() {
        return entityResolver;
    }

    public LabelResolver getLabelResolver() {
        return labelResolver;
    }

    public MetaActionHandler getMetaActionHandler() {
        return metaActionHandler;
    }

    public MetaHandlerFactory getMetaHandlerFactory() {
        return metaHandlerFactory;
    }

    public OptionBuilder<SelectOption> getOptionBuilder() {
        return optionBuilder;
    }

    public GenericEntityConverter getGenericEntityConverter() {
        return genericEntityConverter;
    }
}
